package com.macllvm.whale.net;

import android.util.Log;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import com.macllvm.whale.utils.NetworkTools;
import com.macllvm.whale.protocol.ProtocolBase;
import com.macllvm.whale.protocol.ProtocolController;


public class TCPServer extends Thread {
    private static final String TAG = "TCPServer";
    private ServerSocketChannel mServerSocketChannel;
    private ProtocolController mController;
    private Selector mSelector;
    private boolean isRunning = true;

    public TCPServer(ProtocolController c) throws IOException {
        mController = c;
        mServerSocketChannel = ServerSocketChannel.open();
        mServerSocketChannel.configureBlocking(false);
        mServerSocketChannel.socket().bind(new InetSocketAddress(NetworkTools.getLocalIP(), ProtocolBase.IPMSG_PORT));
        mServerSocketChannel.socket().setReuseAddress(true);
        mSelector = Selector.open();
        mServerSocketChannel.register(mSelector, SelectionKey.OP_ACCEPT);
    }

    @Override
    public void run() {
        try {
            while (isRunning) {
                int n = mSelector.select(200);
                if (n > 0) {
                    Iterator iterator = mSelector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = (SelectionKey) iterator.next();
                        if (key.isAcceptable()) {
                            handleAccept(key);
                        }
                        iterator.remove();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleAccept(SelectionKey key) throws IOException {
        ServerSocketChannel mServerSocketChannel = (ServerSocketChannel)key.channel();
        SocketChannel socketChannel = mServerSocketChannel.accept();
        mController.handleSendClient(socketChannel);
    }

    public void stopServer() {
        isRunning = false;
        try{
            if(null != mServerSocketChannel && mServerSocketChannel.isOpen())
                mServerSocketChannel.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

}